package com.jy.project.service.imp;

import com.jy.project.domain.*;
import com.jy.project.dto.*;
import com.jy.project.enums.ApplyTypeEnum;
import com.jy.project.ex.BizException;
import com.jy.project.mapper.ApplyMapper;
import com.jy.project.mapper.SignMapper;
import com.jy.project.mapper.ToDoTasksMapper;
import com.jy.project.mapper.UserMapper;
import com.jy.project.service.ApplyService;
import com.jy.project.service.MaterialService;
import com.jy.project.service.ToDoTasksService;
import com.jy.project.vo.SignVO;
import com.jy.project.vo.ToDoTasksVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.PostConstruct;
import java.util.*;

@Slf4j
@Service
public class ToExamineServiceImpl implements ToExamineService {

    @Autowired
    @Qualifier("applyCollectServiceImpl")
    private ApplyService applyCollectServiceImpl;

    @Autowired
    @Qualifier("applyStockReturnServiceImpl")
    private ApplyService applyStockReturnServiceImpl;

    @Autowired
    @Qualifier("applyBorrowServiceImpl")
    private ApplyService applyBorrowServiceImpl;

    @Autowired
    @Qualifier("applyRenewServiceImpl")
    private  ApplyService  applyRenewServiceImpl;

    @Autowired
    @Qualifier("applyReturnServiceImpl")
    private ApplyReturnServiceImpl  applyReturnServiceImpl;

    @Autowired
    @Qualifier("applyInsertMaterialServiceImpl")
    private ApplyInsertMaterialServiceImpl  applyInsertMaterialServiceImpl;


    @Autowired
    @Qualifier("applyHandoverServiceImpl")
    private ApplyHandoverServiceImpl applyHandoverServiceImpl;


    @Autowired
    private ApplyMapper applyMapper;

    @Autowired
    private SignMapper signMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ToDoTasksMapper toDoTasksMapper;

    @Autowired
    private ToDoTasksService toDoTasksService;

    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;

    @Autowired
    private TransactionDefinition transactionDefinition;


    @Autowired
    private MaterialService materialService;




    private  Map<Integer, ApplyService> map = null;

    @PostConstruct
    public void init(){
        log.info("ToExamineServiceImpl init 加载 map");
        map=new HashMap<>();
        map.put(ApplyTypeEnum.COLLECT.getCode(),applyCollectServiceImpl);
        map.put(ApplyTypeEnum.BORROW.getCode(),applyBorrowServiceImpl);
        map.put(ApplyTypeEnum.RENEW.getCode(),applyRenewServiceImpl);
        map.put(ApplyTypeEnum.RETURN.getCode(),applyReturnServiceImpl);
        map.put(ApplyTypeEnum.STOCK_RETURN.getCode(),applyStockReturnServiceImpl);
        map.put(ApplyTypeEnum.INSERT_MATERIAL.getCode(),applyInsertMaterialServiceImpl);
        map.put(ApplyTypeEnum.HANDOVERL.getCode(),applyHandoverServiceImpl);
    }

    @Override
    public boolean applyAdopt(ApplyAdoptDTO dto) {
        String applyNo = dto.getApplyNo();
        Long userId = dto.getUserId();
        ToDoTasksDTO toDoTasksDTO=new ToDoTasksDTO();
        toDoTasksDTO.setApplyNo(applyNo);
        toDoTasksDTO.setUserId(userId);
        ToDoTasksVO toDoTasksVO = toDoTasksService.getToDoTasksVO(toDoTasksDTO);
        if (toDoTasksVO==null){
            throw new BizException("找不到当前待办任务");
        }
        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
        boolean bl= false;
        try {
            SignQueryDTO queryDTO=new SignQueryDTO();
            queryDTO.setUserId(userId);
            queryDTO.setApplyNo(applyNo);
            SignVO childSignVO = toDoTasksService.getChildSignVO(queryDTO);
            if (childSignVO==null){
                throw new BizException("找不到当前用户加签数据");
            }
            if (childSignVO.getStatus()!=0){
                throw new BizException("当前用户已经不是待处理状态");
            }
            Sign sign=new Sign();
            sign.setId(childSignVO.getId());
            sign.setStatus(1);
            int i = signMapper.updateByPrimaryKeySelective(sign);
            if (i <1){
                throw new BizException("当前用户已经操作过了");
            }
            SignQueryDTO signQueryDTO=new SignQueryDTO();
            signQueryDTO.setApplyNo(applyNo);
            //所有加签都否同意
            boolean isAllAgree= toDoTasksService.isAllAgree(signQueryDTO);
            if (!isAllAgree){
                dataSourceTransactionManager.commit(transactionStatus);
                return  true;
            }
            Long id = toDoTasksVO.getId();
            boolean alreadyHandle = toDoTasksService.alreadyHandle(id);
            if (alreadyHandle==false){
                throw new BizException("当前流程任务结束失败");
            }
            Example example=new Example(Apply.class);
            example.createCriteria().andEqualTo("applyNo",applyNo);
            Apply aly = applyMapper.selectOneByExample(example);
            if (aly==null){
                throw new BizException("操作记录不存在");
            }
            if (aly.getIsDelete()==1){
                throw new BizException("操作记录被删除");
            }
            if (aly.getStatus()==2){
                throw new BizException("操作已经驳回,无法通过");
            }
            Integer applyType = aly.getApplyType();
            ApplyService applyService = map.get(applyType);
            if (applyService==null){
                throw new BizException("没有该操作类型");
            }
            bl=applyService.applyAdopt(dto);
            if (!bl){
                throw  new BizException("修改通过状态失败");
            }
            Apply apply=new Apply();
            apply.setApplyNo(dto.getApplyNo());
            apply.setStatus(1);
            bl= this.updateStatus(apply);
            if (!bl){
                throw  new BizException("已经是通过状态");
            }
        }catch (Exception e){
            dataSourceTransactionManager.rollback(transactionStatus);
            throw  e;
        }
          dataSourceTransactionManager.commit(transactionStatus);
        return bl;
    }

    private boolean updateStatus(Apply apply){
        Example example =new Example(Apply.class);
        if (StringUtils.isEmpty(apply.getApplyNo())){
            throw  new BizException("审批单号不能为空");
        }

        Apply ly=new Apply();
        BeanUtils.copyProperties(apply,ly);
        ly.setApplyNo(null);
        example.createCriteria().andEqualTo("applyNo",apply.getApplyNo());
        Apply ay = applyMapper.selectOneByExample(example);
        if (ay.getStatus()==1){
            return true;
        }
        int i = applyMapper.updateByExampleSelective(ly, example);
        return i>0;
    }
    @Override
    public boolean applyReject(ApplyAdoptDTO dto) {
        String applyNo = dto.getApplyNo();
        Long userId = dto.getUserId();
        ToDoTasksDTO toDoTasksDTO=new ToDoTasksDTO();
        toDoTasksDTO.setApplyNo(applyNo);
        toDoTasksDTO.setUserId(userId);
        ToDoTasksVO toDoTasksVO = toDoTasksService.getToDoTasksVO(toDoTasksDTO);
        if (toDoTasksVO==null){
            throw new BizException("找不到当前待办任务");
        }
        SignQueryDTO queryDTO=new SignQueryDTO();
        queryDTO.setUserId(userId);
        queryDTO.setApplyNo(applyNo);
        SignVO childSignVO = toDoTasksService.getChildSignVO(queryDTO);
        if (childSignVO==null){
            throw new BizException("找不到当前用户加签数据");
        }
        if (childSignVO.getStatus()!=0){
            throw new BizException("当前用户已经不是待处理状态");
        }
        Sign sign=new Sign();
        sign.setId(childSignVO.getId());
        sign.setStatus(2);
        int i = signMapper.updateByPrimaryKeySelective(sign);
        if (i <1){
            throw new BizException("当前用户已经操作过了");
        }
        //剩下未审批的用户,不需要审批
        signMapper.deleteNotOperated(applyNo);

        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
        boolean bl=false;
        try {
            Long id = toDoTasksVO.getId();
            boolean b = toDoTasksService.rejectHandle(id);
            if (b==false){
                throw new BizException("ToDoTasks处理失败");
            }
            Example example=new Example(Apply.class);
            example.createCriteria().andEqualTo("applyNo",applyNo);
            Apply aly = applyMapper.selectOneByExample(example);
            if (aly==null){
                throw new BizException("操作记录不存在");
            }
            if (aly.getIsDelete()==1){
                throw new BizException("操作记录被删除");
            }
            if (aly.getStatus()==1){
                throw new BizException("已经是通过状态,无法驳回");
            }
            Integer applyType = aly.getApplyType();
            ApplyService applyService = map.get(applyType);
            if (applyService==null){
                throw new BizException("没有该操作类型");
            }
            bl=applyService.applyReject(dto);
            if (!bl){
                throw  new BizException("修改驳回状态失败");
            }
            Apply apply=new Apply();
            apply.setApplyNo(dto.getApplyNo());
            apply.setStatus(2);
            bl = this.updateStatus(apply);
            if (!bl){
                throw  new BizException("已经是驳回状态");
            }

        }catch (Exception e){
            dataSourceTransactionManager.rollback(transactionStatus);
            throw  e;
        }
          dataSourceTransactionManager.commit(transactionStatus);
        return bl;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public synchronized boolean  reapply(ApplyReapplyDTO dto) {
        String applyNo = dto.getApplyNo();
        Apply apply = applyMapper.getApplyByApplyNo(applyNo);
        if (apply==null){
            throw new BizException("找不到单据");
        }
        Integer status = apply.getStatus();
        if (status!=2){
            throw new BizException("不是驳回状态,不能发起");
        }
        Integer applyType = apply.getApplyType();
        if (applyType==ApplyTypeEnum.INSERT_MATERIAL.getCode()){
            MaterialUpdateDTO materialUpdateDTO=new MaterialUpdateDTO();
            BeanUtils.copyProperties(dto,materialUpdateDTO);
            boolean isUpdate = materialService.updateReapply(materialUpdateDTO);
            if (!isUpdate){
                throw new BizException("物资资产修改错误");
            }
            Long managementUserId = dto.getManagementUserId();
            apply.setManagementUserId(managementUserId);
            Long useUserId = dto.getUseUserId();
            apply.setUseUserId(useUserId);
            apply.setUpdateAt(new Date());
            User useUser = userMapper.selectByPrimaryKey(useUserId);
            if (useUser!=null) {
                apply.setUseCompanyNo(useUser.getCompanyNo());
                apply.setUseCompanyName(useUser.getCompanyName());
                apply.setUseDeptNo(useUser.getDeptNo());
                apply.setUseDeptName(useUser.getDeptName());
                apply.setUseUserId(useUser.getId());
                apply.setUseNickName(useUser.getNickName());
            }
        }
        Date date = new Date();
        apply.setCreateAt(date);
        apply.setUpdateAt(date);
        apply.setUpdateDay(date);
        apply.setStatus(0);
        int i = applyMapper.updateByPrimaryKeySelective(apply);
        if (i<1){
            throw new BizException("审核表修改失败");
        }
        ToDoTasks tasks=new ToDoTasks();
        tasks.setApplyNo(applyNo);
        ToDoTasks t = toDoTasksMapper.selectOne(tasks);
        if (t!=null){
            int i1 = toDoTasksMapper.deleteByPrimaryKey(t.getId());
            if (i1<1){
                throw new BizException("任务表删除失败");
            }
        }
        SignDTO signDTO=new SignDTO();
        signDTO.setApplyNo(applyNo);
        List<Sign> list = signMapper.listSign(signDTO);
        if (!list.isEmpty()){
            for (Sign sign : list) {
                int i3 =signMapper.deleteByPrimaryKey(sign.getId());
                if (i3<1){
                    throw new BizException("加签表生成失败败");
                }
            }
        }
        return true;
    }
}
